package com.kmdd.xtds

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding

/**
 * 创建单一项的适配器
 *
 * @param itemsSource       数据源
 * @param viewCreator       View创建方法
 * @param viewHolderBinder  数据绑定方法
 */
fun <Item : Any?, V : ViewBinding> adapterOf(
    itemsSource: List<Item>?,
    viewCreator: (inflater: LayoutInflater, root: ViewGroup, attachToRoot: Boolean) -> V,
    viewHolderBinder: (holder: BindingViewHolder<V>, item: Item, position: Int) -> Unit,
): RecyclerView.Adapter<BindingViewHolder<V>> {
    return SimpleAdapter(
        itemsSource = itemsSource,
        viewHolderCreator = { parent, _ ->
            parent.viewHolderFrom(viewCreator)
        },
        viewHolderBinder = viewHolderBinder
    )
}

/**
 * 创建多类型项的适配器
 *
 * @param itemsSource       数据源
 * @param viewTypeFunction  Item项类型，需要返回[viewsCreator]集合的索引
 * @param viewsCreator      View创建方法
 * @param viewHolderBinder  数据绑定方法
 */
fun <Item : Any?> adapterOf(
    itemsSource: List<Item>?,
    viewTypeFunction: ((Item,Int) -> Int),
    viewsCreator: List<(inflater: LayoutInflater, root: ViewGroup, attachToRoot: Boolean) -> ViewBinding>,
    viewHolderBinder: (holder: BindingViewHolder<*>, item: Item, position: Int) -> Unit,
): RecyclerView.Adapter<BindingViewHolder<*>> {
    return SimpleAdapter(
        itemsSource = itemsSource,
        viewTypeFunction = viewTypeFunction,
        viewHolderCreator = { parent, viewType ->
            parent.viewHolderFrom(viewsCreator[viewType])
        },
        viewHolderBinder = viewHolderBinder
    )
}

/**
 * 创建单一项的适配器
 *
 * @param diffCallback      数据差异判断
 * @param viewCreator       View创建方法
 * @param viewHolderBinder  数据绑定方法
 */
fun <Item : Any?, VB : ViewBinding> listAdapterOf(
    diffCallback: DiffUtil.ItemCallback<Item>,
    viewCreator: (inflater: LayoutInflater, root: ViewGroup, attachToRoot: Boolean) -> VB,
    viewHolderBinder: (holder: BindingViewHolder<VB>, item: Item, position: Int) -> Unit,
): ListAdapter<Item, BindingViewHolder<VB>> {
    return SimpleListAdapter(
        diff = diffCallback,
        viewHolderCreator = { parent, _ ->
            parent.viewHolderFrom(viewCreator)
        },
        viewHolderBinder = viewHolderBinder
    )
}

/**
 * 创建多类型项的适配器
 *
 * @param diffCallback      数据差异判断
 * @param viewTypeFunction  Item项类型，需要返回[viewsCreator]集合的索引
 * @param viewsCreator      View创建方法
 * @param viewHolderBinder  数据绑定方法
 */
fun <Item : Any?> listAdapterOf(
    diffCallback: DiffUtil.ItemCallback<Item>,
    viewTypeFunction: ((Item,Int) -> Int),
    viewsCreator: List<(inflater: LayoutInflater, root: ViewGroup, attachToRoot: Boolean) -> ViewBinding>,
    viewHolderBinder: (holder: BindingViewHolder<*>, item: Item, position: Int) -> Unit,
): ListAdapter<Item, BindingViewHolder<*>> {
    return SimpleListAdapter(
        diff = diffCallback,
        viewTypeFunction = viewTypeFunction,
        viewHolderCreator = { parent, viewType ->
            parent.viewHolderFrom(viewsCreator[viewType])
        },
        viewHolderBinder = viewHolderBinder
    )
}

/**
 * 基础的列表适配器
 */
class SimpleAdapter<Item : Any?, VH : RecyclerView.ViewHolder>(
    private val itemsSource: List<Item>?,
    private val viewHolderCreator: (ViewGroup, Int) -> VH,
    private val viewHolderBinder: (holder: VH, item: Item, position: Int) -> Unit,
    private val viewTypeFunction: ((Item,Int) -> Int)? = null,
) : RecyclerView.Adapter<VH>() {

    override fun getItemViewType(position: Int): Int =
        viewTypeFunction?.invoke(itemsSource!![position],position) ?: super.getItemViewType(position)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        return viewHolderCreator.invoke(parent, viewType)
    }

    override fun onBindViewHolder(holder: VH, position: Int) {
        viewHolderBinder.invoke(holder, itemsSource!![position], position)
    }

    override fun getItemCount(): Int {
        return itemsSource?.size ?: 0
    }
}

/**
 * 支持数据差异更新的列表适配器
 */
class SimpleListAdapter<Item : Any?, VH : RecyclerView.ViewHolder>(
    diff: DiffUtil.ItemCallback<Item>,
    private val viewHolderCreator: (ViewGroup, Int) -> VH,
    private val viewHolderBinder: (holder: VH, item: Item, position: Int) -> Unit,
    private val viewTypeFunction: ((Item,Int) -> Int)? = null,
) : ListAdapter<Item, VH>(diff) {

    override fun getItemViewType(position: Int): Int =
        viewTypeFunction?.invoke(getItem(position),position) ?: super.getItemViewType(position)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        return viewHolderCreator.invoke(parent, viewType)
    }

    override fun onBindViewHolder(holder: VH, position: Int) {
        viewHolderBinder.invoke(holder, getItem(position), position)
    }
}